package com.ruoyi.core.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.Configuration;
import com.qiniu.util.Auth;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.core.domain.FileDo;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.core.mapper.SysFileMapper;

import com.ruoyi.core.service.ISysFileService;
import com.ruoyi.common.core.text.Convert;
import org.springframework.transaction.annotation.Transactional;

/**
 * 文件管理Service业务层处理
 * 
 * @author lgc
 * @date 2020-12-01
 */
@Service
public class SysFileServiceImpl implements ISysFileService 
{
    private static final String QINIU_ACCESS_KEY = "quR3bktIBSE_tsm62gV3SsXX7AGlVAznNRHgDEkg";
    private static final String QINIU_SECRET_KEY = "H_bAT5u6G8XSn-qVcWkeGY-37w4o526Mqtjl2n4R";
    private static final String QINIU_BUCKET = "hssc";
    private static final String QINIU_ACCESS_URL = "http://hs.886315.com/";
    private static final String KEY_TOKEN = "qiniu_token";
    private static final Map<String, Object> FILE_CACHE = new HashMap<>();

    private UploadManager uploadManager;


    @Autowired
    private SysFileMapper sysFileMapper;

    public SysFileServiceImpl() {
        Configuration configuration = new Configuration(Zone.zone0());
        uploadManager = new UploadManager(configuration);
    }


    @Override
    @Transactional(rollbackFor = {Exception.class})
    public FileDo upload(Long userId, byte[] fileBytes, String fileName) {
        String originName = fileName;
        if (fileBytes == null || fileBytes.length < 1) {
            throw new BusinessException("上传文件不能为空");
        }

        try {
            String token = getQiniuToken(QINIU_ACCESS_KEY, QINIU_SECRET_KEY, QINIU_BUCKET);

            StringBuilder fileNameBuilder = new StringBuilder();
            fileNameBuilder.append(QINIU_BUCKET);
            fileNameBuilder.append("/");
            fileNameBuilder.append(DateUtils.formatDate(new Date(), "yyyyMMddHHmmsSS"));
            String extension = StringUtils.isBlank(fileName) ? "" : fileName.substring(fileName.indexOf("."));
            if (StringUtils.isNotBlank(extension)) {
                fileNameBuilder.append(extension);
            }
            fileName = fileNameBuilder.toString();

            //上传文件
            Response response = uploadManager.put(fileBytes, fileName, token);
            if (!response.isOK()) {
                throw new BusinessException("文件上传失败");
            }

            StringBuilder urlBuilder = new StringBuilder();
            urlBuilder.append(QINIU_ACCESS_URL);
            if (QINIU_ACCESS_URL.endsWith("/")) {
                urlBuilder.append(fileName);
            } else {
                urlBuilder.append("/");
                urlBuilder.append(fileName);
            }
            //
            FileDo fileDO = new FileDo();
            fileDO.setCreateDate(new Date());
            fileDO.setUrl(urlBuilder.toString());
            fileDO.setOriginName(originName);
            fileDO.setUserId(userId);
            Integer result = insertSysFile(fileDO);
            if (result < 1) {
                throw new BusinessException("文件存档失败");
            }
            return fileDO;
        } catch (QiniuException ex) {
            ex.printStackTrace();
            throw new BusinessException("文件上传失败", ex);
        }
    }

    /**
     * 获取七牛云配置
     *
     * @return
     */
//    private JSONObject getQiniuConfig() {
//        String qiniuConfig = configService.getValuByKey(QINIU_CONFIG);
//        JSONObject jsonObject = JSON.parseObject(qiniuConfig);
//        return jsonObject;
//    }


    /**
     * 获取token
     *
     * @param accessKey
     * @param secretKey
     * @param bucket
     * @return
     */
    private String getQiniuToken(String accessKey, String secretKey, String bucket) {
        SysFileServiceImpl.QiniuToken qiniuToken = (SysFileServiceImpl.QiniuToken) FILE_CACHE.get(KEY_TOKEN);
        //if (qiniuToken == null || qiniuToken.isExpire()) {
        String tokenString = Auth.create(accessKey, secretKey).uploadToken(bucket);
        qiniuToken = new SysFileServiceImpl.QiniuToken(tokenString, 7 * 60 * 60);
        FILE_CACHE.put(KEY_TOKEN, qiniuToken);
        //}
        return qiniuToken.getToken();
    }


    static class QiniuToken {
        private String token;
        private long created_date;
        private long expireTime;


        public QiniuToken(String token, long expireSeconds) {
            this.token = token;
            this.created_date = new Date().getTime();
            this.expireTime = created_date + expireSeconds * 1000;
        }

        public String getToken() {
            return token;
        }

        public boolean isExpire() {
            //提前30分钟过期
            long currentTime = System.currentTimeMillis() + 30 * 60 * 1000;
            if (currentTime < expireTime) {
                return false;
            }
            return true;
        }
    }
    
    
    

    /**
     * 查询文件管理
     * 
     * @param id 文件管理ID
     * @return 文件管理
     */
    @Override
    public FileDo selectSysFileById(Long id)
    {
        return sysFileMapper.selectSysFileById(id);
    }

    /**
     * 查询文件管理列表
     * 
     * @param sysFile 文件管理
     * @return 文件管理
     */
    @Override
    public List<FileDo> selectSysFileList(FileDo sysFile)
    {
        return sysFileMapper.selectSysFileList(sysFile);
    }

    /**
     * 新增文件管理
     * 
     * @param sysFile 文件管理
     * @return 结果
     */
    @Override
    public int insertSysFile(FileDo sysFile)
    {
        return sysFileMapper.insertSysFile(sysFile);
    }

    /**
     * 修改文件管理
     * 
     * @param sysFile 文件管理
     * @return 结果
     */
    @Override
    public int updateSysFile(FileDo sysFile)
    {
        return sysFileMapper.updateSysFile(sysFile);
    }

    /**
     * 删除文件管理对象
     * 
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteSysFileByIds(String ids)
    {
        return sysFileMapper.deleteSysFileByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除文件管理信息
     * 
     * @param id 文件管理ID
     * @return 结果
     */
    @Override
    public int deleteSysFileById(Long id)
    {
        return sysFileMapper.deleteSysFileById(id);
    }
}
